//
// Created by hjie on 23-5-13.
//
#include "./../redis_message.h"
#include <iostream>

void PrintRedisArrayMessage(RedisMessage * message)
{
    for(auto & data : ((RedisMessageArray*)message)->GetMessageVector())
    {
        if (data->GetMessageType() == EmNumberType)
        {
            std::cout << "number :" << ((RedisMessageNumber*)data)->Number() << std::endl;
        }
        else if (data->GetMessageType() == EmLengthStringType)
        {
            std::cout << "string :" << ((RedisMessageLengthString*)data)->Show() << std::endl;
        }
    }
}

void TestStringTypeMessage()
{
    std::string message = "+OK\r\n";

    EmRedisParseStatus status;

    int index = 0;
    RedisMessage * redis_msg = RedisMessage::ParseRedisMessage((const uint8_t*)message.c_str(), message.size(), index, status);
    if (redis_msg)
    {
        std::cout << "value :" << ((RedisMessageString*)redis_msg)->Show() << ":" << std::endl;
        delete redis_msg;
    }
}

void TestLengthStringTypeMessage()
{
    std::string message_one = "$4\r\nABCD\r\n";
    std::string message_two = "$0\r\n\r\n";
    std::string message_three = "$-1\r\n";

    EmRedisParseStatus status;
    int index = 0;
    RedisMessage * message = RedisMessage::ParseRedisMessage((const uint8_t*)message_one.c_str(), message_one.size(), index, status);
    if (message)
    {
        std::cout << "value :" << ((RedisMessageLengthString*)message)->Show() << ":length :" << ((RedisMessageLengthString*)message)->GetLength() << std::endl;
        std::cout << "use_length:" << index << std::endl;

        delete message;
    }
    message = RedisMessage::ParseRedisMessage((const uint8_t*)message_two.c_str(), message_two.size(), index, status);
    if (message)
    {
        std::cout << "length :" << ((RedisMessageLengthString*)message)->GetLength() << std::endl;
        std::cout << "use_length :" << index << std::endl;

        delete message;
    }
    message = RedisMessage::ParseRedisMessage((const uint8_t*)message_three.c_str(), message_three.size(), index, status);
    if (message)
    {
        std::cout << "length :" << ((RedisMessageLengthString*)message)->GetLength() << std::endl;
        std::cout << "use_length :" << index << std::endl;

        delete message;
    }
}

void TestArrayTypeMessage()
{
    std::string message_one = "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n";
    std::string message_two = "*3\r\n$4\r\nABCD\r\n:123456\r\n$5\r\nMNBVC\r\n";

    std::string message_three = "*0\r\n";
    std::string message_four  = "*-1\r\n";

    EmRedisParseStatus status;

    int index = 0;
    RedisMessage * message = RedisMessage::ParseRedisMessage((const uint8_t*)message_one.c_str(), message_one.size(), index, status);
    if (message)
    {
        PrintRedisArrayMessage(message);
        delete message;
    }
     message = RedisMessage::ParseRedisMessage((const uint8_t*)message_two.c_str(), message_two.size(), index, status);
    if (message)
    {
        PrintRedisArrayMessage(message);
        delete message;
    }

    message = RedisMessage::ParseRedisMessage((const uint8_t*)message_three.c_str(), message_three.size(), index, status);
    if (message)
    {
        PrintRedisArrayMessage(message);
        delete message;
    }
    else
    {
        std::cout << "parse redis array failed msg : " << message_three << std::endl;
    }
    message = RedisMessage::ParseRedisMessage((const uint8_t*)message_four.c_str(), message_four.size(), index, status);
    if (message)
    {
        PrintRedisArrayMessage(message);
        delete message;
    }
    else
    {
        std::cout << "parse redis array failed msg : " << message_four << std::endl;
    }
}

void TestNumberTypeMessage()
{
    std::string message_one = ":123456\r\n";
    int index = 0;
    EmRedisParseStatus status;
    RedisMessage * message = RedisMessage::ParseRedisMessage((const uint8_t*)message_one.c_str(), message_one.size(), index, status);
    if (message)
    {
        std::cout << "number :" << ((RedisMessageNumber*)message)->Number() << std::endl;
        std::cout << "use_length :" << index << std::endl;

        delete message;
    }
}

void TestErrorTypeMessage()
{
    std::string message_one = "-Error unknown command\r\n";
    EmRedisParseStatus status;

    int index = 0;
    RedisMessage * message = RedisMessage::ParseRedisMessage((const uint8_t*)message_one.c_str(), message_one.size(), index, status);
    if (message)
    {
        std::cout << "error msg :"  << ((RedisMessageError*)message)->Error() << std::endl;
        std::cout << "use_length :" << index << std::endl;

        delete message;
    }
}

void TestParseCommandMessage()
{
    std::string cmd_msg = "get hello world";
    RedisMessage * message = RedisMessage::ParseCommand(cmd_msg);

    std::string result;
    if (message || message->GetMessageType() == EmArrayStringType)
    {
        ((RedisMessageArray*)message)->ComposeMessage(result);
        std::cout << result << "|end\n";
    }
}

int main()
{
    // TestStringTypeMessage();
    // TestLengthStringTypeMessage();
    // TestNumberTypeMessage();
    // TestErrorTypeMessage();
    // TestArrayTypeMessage();
    // TestParseCommandMessage();
    return EXIT_SUCCESS;
}